package genetic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Random;

/**
 *
 * @author shanki
 */
class Roulette<T extends Chromosome<T,C>, C> {
    private ArrayList<T> items;
    private double[] sums;
    private double max;
    
    private Random random           = new Random(new Date().getTime());
    
    public Roulette(ArrayList<T> items) {
        if (items == null) throw new IllegalArgumentException("items cannot be null");
        if (items.isEmpty()) throw new IllegalArgumentException("items have to have at least one element");
        
        this.items  = items;
        sums        = new double[items.size()];
        
        compute();
    }
    
    private void compute() {
        
        double sum  = 0;
        
        for (int i = 0; i < items.size(); ++ i) {
            sum     += items.get(i).getValue();
            sums[i] = sum;
        }
        
        max = sum;
    }

//    private void compute() {        
//        T maxItem = Collections.max(items, new Comparator<T>() {
//
//            @Override
//            public int compare(T arg0, T arg1) {
//                return Double.compare(arg0.getValue(), arg1.getValue());
//            }
//
//        });
//        
//        double maxObjective  = maxItem.getValue();
//        
//        double sum  = 0;
//        
//        for (int i = 0; i < items.size(); ++ i) {
//            sum     += transform(items.get(i).getValue(), maxObjective);
//            sums[i] = sum;
//        }
//        
//        max = sum;
//    }
//    
//    private double transform(double value, double max) {
//        // x0=0 ........y0=1
//        // x1=max ..... y1=0
//        
//        double k    = (0 - 1) / (max - 0);
//        double q    = (1*max - 0*0) / (max - 0);
//        
//        return k * value + q;
//    }
    
    public T select() {
        double value    = random.nextDouble() * max;
        
        for (int i = 0; i < items.size(); ++i) {
            if (value <= sums[i]) {
                return items.get(i);
            }
        }
        
        throw new RuntimeException("This line should have never been hit");
    }
}